#!/bin/bash

# DTU开发板刷写脚本
# 支持通过Type-C接口刷写DTU固件到开发板
# 支持三种DTU版本：Ethernet-only, WiFi+Ethernet, 4G+Ethernet

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 项目配置
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
DTU_BINARY="$PROJECT_DIR/cmake-build-debug/bin/iot_dtu_c"
SERIAL_PORT="/dev/tty.usbserial-1130"
DTU_VERSION="ethernet"  # 默认版本

# 日志函数
log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

log_debug() {
    echo -e "${BLUE}[DEBUG]${NC} $1"
}

# 显示帮助信息
show_help() {
    echo "=========================================="
    echo "    DTU开发板刷写脚本 v1.0"
    echo "=========================================="
    echo ""
    echo "用法: $0 [DTU版本] [开发板类型] [选项]"
    echo ""
    echo "DTU版本选项:"
    echo "  --ethernet      刷写纯网口版本（默认）"
    echo "  --wifi          刷写WiFi+网口版本"
    echo "  --4g            刷写4G+网口版本"
    echo ""
    echo "开发板类型:"
    echo "  esp32           ESP32系列开发板（通过Type-C刷写）"
    echo "  linux           Linux开发板（树莓派、Orange Pi等，通过网络）"
    echo "  stm32           STM32系列开发板（通过Type-C刷写）"
    echo "  auto            自动检测开发板类型（默认）"
    echo ""
    echo "其他选项:"
    echo "  -h, --help      显示此帮助信息"
    echo "  -p, --port PORT 指定串口设备（默认: $SERIAL_PORT）"
    echo "  -b, --baud RATE 指定波特率（默认: 921600）"
    echo "  -i, --ip IP     指定开发板IP地址（Linux开发板必需）"
    echo "  --check         仅检查开发板连接状态"
    echo "  --build         刷写前重新编译固件"
    echo ""
    echo "常用示例:"
    echo "  $0                                 # 自动检测并刷写默认版本"
    echo "  $0 --wifi esp32                   # 刷写WiFi版本到ESP32开发板"
    echo "  $0 --4g linux -i 192.168.1.100   # 刷写4G版本到Linux开发板"
    echo "  $0 --build --ethernet esp32       # 重新编译并刷写纯网口版本"
    echo "  $0 --check                        # 检查开发板连接状态"
    echo ""
    echo "注意事项:"
    echo "  - 刷写前请确保开发板通过Type-C连接到电脑"
    echo "  - Linux开发板需要指定IP地址进行网络刷写"
    echo "  - 刷写前会自动编译对应版本的固件"
    echo "  - 刷写完成后开发板会自动重启"
    echo ""
}

# 检查开发板连接
check_connection() {
    log_info "检查开发板连接状态..."
    
    # 检查串口设备
    if [[ -e "$SERIAL_PORT" ]]; then
        log_info "找到串口设备: $SERIAL_PORT"
        
        # 获取设备信息
        if command -v system_profiler >/dev/null 2>&1; then
            local vendor_id=$(system_profiler SPUSBDataType | grep -A 10 -B 5 "$(basename $SERIAL_PORT)" | grep "Vendor ID" | awk '{print $3}')
            local product_id=$(system_profiler SPUSBDataType | grep -A 10 -B 5 "$(basename $SERIAL_PORT)" | grep "Product ID" | awk '{print $3}')
            
            log_info "设备信息: Vendor ID: $vendor_id, Product ID: $product_id"
            
            case "$vendor_id" in
                "0x1a86")
                    log_info "检测到CH340/CH341芯片，常用于ESP32/Arduino开发板"
                    return 0
                    ;;
                "0x10c4")
                    log_info "检测到CP210x芯片，常用于ESP32开发板"
                    return 0
                    ;;
                "0x0403")
                    log_info "检测到FTDI芯片"
                    return 0
                    ;;
                *)
                    log_warn "未知的USB芯片类型"
                    return 0
                    ;;
            esac
        fi
    else
        log_error "未找到串口设备: $SERIAL_PORT"
        log_info "可用的串口设备:"
        ls /dev/tty* | grep -E "(USB|ACM|tty\.usb)" || log_warn "未找到任何串口设备"
        return 1
    fi
}

# 自动检测开发板类型
detect_board_type() {
    log_info "自动检测开发板类型..."
    
    # 基于USB设备信息检测
    if command -v system_profiler >/dev/null 2>&1; then
        local vendor_id=$(system_profiler SPUSBDataType | grep -A 10 -B 5 "$(basename $SERIAL_PORT)" | grep "Vendor ID" | awk '{print $3}')
        
        case "$vendor_id" in
            "0x1a86"|"0x10c4")
                echo "esp32"
                return 0
                ;;
        esac
    fi
    
    # 默认返回esp32
    echo "esp32"
}

# 编译程序
build_program() {
    local dtu_version="$1"
    log_info "使用build.sh脚本编译DTU程序 ($dtu_version 版本)..."
    cd "$PROJECT_DIR"

    # 构建编译参数
    local build_args=""
    case "$dtu_version" in
        "ethernet")
            build_args="--ethernet"
            ;;
        "wifi")
            build_args="--wifi"
            ;;
        "4g")
            build_args="--4g"
            ;;
        *)
            log_warn "未知的DTU版本: $dtu_version，使用默认版本"
            build_args=""
            ;;
    esac

    # 调用已有的构建脚本
    if [[ -x "scripts/build.sh" ]]; then
        log_info "执行命令: ./scripts/build.sh $build_args"
        ./scripts/build.sh $build_args
        local result=$?

        if [[ $result -eq 0 ]]; then
            log_info "编译成功 ($dtu_version 版本)"
            return 0
        else
            log_error "编译失败"
            return 1
        fi
    else
        log_error "未找到build.sh脚本或脚本不可执行"
        log_info "请确保scripts/build.sh存在且可执行"
        return 1
    fi
}

# 刷写ESP32开发板
flash_esp32() {
    local dtu_version="$1"
    log_info "刷写ESP32开发板 ($dtu_version 版本)..."

    # 检查esptool是否安装
    if ! command -v esptool.py >/dev/null 2>&1; then
        log_error "未找到esptool.py，请先安装ESP-IDF或esptool"
        log_info "安装命令: pip install esptool"
        return 1
    fi

    # 注意：这里需要将C程序转换为ESP32固件
    log_warn "注意: 当前的iot_dtu_c程序是为Linux编译的"
    log_warn "要在ESP32上运行，需要使用ESP-IDF重新编译"
    log_info "建议步骤:"
    log_info "1. 安装ESP-IDF: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/"
    log_info "2. 创建ESP32版本的DTU项目"
    log_info "3. 移植代码到ESP-IDF框架"
    log_info "4. 根据DTU版本($dtu_version)配置相应的网络功能"

    return 1
}

# 刷写Linux开发板
flash_linux() {
    local board_ip="$1"
    local dtu_version="$2"
    log_info "刷写Linux开发板 ($dtu_version 版本)..."

    if [[ -z "$board_ip" ]]; then
        log_error "请指定开发板IP地址，使用 -i 参数"
        return 1
    fi

    # 检查网络连接
    if ! ping -c 1 "$board_ip" >/dev/null 2>&1; then
        log_error "无法连接到开发板: $board_ip"
        return 1
    fi

    log_info "通过SCP传输程序到开发板..."
    scp "$DTU_BINARY" "root@$board_ip:/usr/local/bin/iot_dtu_c"

    if [[ $? -eq 0 ]]; then
        log_info "程序传输成功 ($dtu_version 版本)"
        log_info "SSH连接到开发板运行程序:"
        log_info "  ssh root@$board_ip"
        log_info "  chmod +x /usr/local/bin/iot_dtu_c"
        log_info "  /usr/local/bin/iot_dtu_c --test-mode"

        # 根据DTU版本提供相应的配置建议
        case "$dtu_version" in
            "wifi")
                log_info "WiFi版本配置提示:"
                log_info "  - 确保开发板支持WiFi功能"
                log_info "  - 配置WiFi网络参数"
                ;;
            "4g")
                log_info "4G版本配置提示:"
                log_info "  - 确保开发板连接了4G模块"
                log_info "  - 配置APN和网络参数"
                ;;
            "ethernet")
                log_info "以太网版本配置提示:"
                log_info "  - 确保网线连接正常"
                log_info "  - 配置IP地址和网关"
                ;;
        esac

        return 0
    else
        log_error "程序传输失败"
        return 1
    fi
}

# 刷写STM32开发板
flash_stm32() {
    local dtu_version="$1"
    log_info "刷写STM32开发板 ($dtu_version 版本)..."

    # 检查OpenOCD是否安装
    if ! command -v openocd >/dev/null 2>&1; then
        log_error "未找到OpenOCD，请先安装"
        log_info "安装命令: brew install openocd"
        return 1
    fi

    log_warn "注意: 当前的iot_dtu_c程序是为Linux编译的"
    log_warn "要在STM32上运行，需要使用ARM工具链重新编译"
    log_info "建议步骤:"
    log_info "1. 安装ARM工具链: brew install arm-none-eabi-gcc"
    log_info "2. 使用STM32CubeMX创建项目"
    log_info "3. 移植DTU代码到STM32项目"
    log_info "4. 根据DTU版本($dtu_version)配置相应的外设"

    return 1
}

# 主函数
main() {
    local board_type=""
    local board_ip=""
    local baud_rate="921600"
    local check_only=false
    local build_first=false
    local dtu_version="ethernet"  # 默认版本
    
    # 解析命令行参数
    while [[ $# -gt 0 ]]; do
        case $1 in
            -h|--help)
                show_help
                exit 0
                ;;
            -p|--port)
                SERIAL_PORT="$2"
                shift 2
                ;;
            -b|--baud)
                baud_rate="$2"
                shift 2
                ;;
            -i|--ip)
                board_ip="$2"
                shift 2
                ;;
            --check)
                check_only=true
                shift
                ;;
            --build)
                build_first=true
                shift
                ;;
            --ethernet)
                dtu_version="ethernet"
                shift
                ;;
            --wifi)
                dtu_version="wifi"
                shift
                ;;
            --4g)
                dtu_version="4g"
                shift
                ;;
            esp32|linux|stm32|auto)
                board_type="$1"
                shift
                ;;
            *)
                log_error "未知选项: $1"
                show_help
                exit 1
                ;;
        esac
    done
    
    echo -e "${BLUE}=== DTU开发板刷写工具 ===${NC}"
    echo "项目目录: $PROJECT_DIR"
    echo "程序文件: $DTU_BINARY"
    echo "串口设备: $SERIAL_PORT"
    echo "DTU版本: $dtu_version"
    echo ""
    
    # 检查程序文件是否存在
    if [[ ! -f "$DTU_BINARY" ]]; then
        log_error "未找到程序文件: $DTU_BINARY"
        log_info "请先编译程序: ./scripts/build.sh"
        log_info "或使用 --build 参数自动编译"
        exit 1
    fi
    
    # 检查连接
    if ! check_connection; then
        exit 1
    fi
    
    if [[ "$check_only" == true ]]; then
        log_info "连接检查完成"
        exit 0
    fi
    
    # 重新编译（如果需要）
    if [[ "$build_first" == true ]]; then
        if ! build_program "$dtu_version"; then
            exit 1
        fi
    fi
    
    # 自动检测开发板类型
    if [[ "$board_type" == "auto" || -z "$board_type" ]]; then
        board_type=$(detect_board_type)
        log_info "检测到开发板类型: $board_type"
    fi
    
    # 根据开发板类型执行刷写
    case "$board_type" in
        esp32)
            flash_esp32 "$dtu_version"
            ;;
        linux)
            flash_linux "$board_ip" "$dtu_version"
            ;;
        stm32)
            flash_stm32 "$dtu_version"
            ;;
        *)
            log_error "不支持的开发板类型: $board_type"
            show_help
            exit 1
            ;;
    esac
}

# 运行主函数
main "$@"
